#include "stdafx.h"

Limit::Limit(Trigger ^trg, Account ^acc)
{
	account = acc;
	trigger = trg;

	profit_1_dest = acc->LimitOptions->optLimit_1_Dest;
	profit_2_dest = acc->LimitOptions->optLimit_2_Dest;
	profit_3_dest = acc->LimitOptions->optLimit_3_Dest;
	profit_4_dest = acc->LimitOptions->optLimit_4_Dest;
	profit_1_prop = acc->LimitOptions->optLimit_1_Prop;
	profit_2_prop = acc->LimitOptions->optLimit_2_Prop;
	profit_3_prop = acc->LimitOptions->optLimit_3_Prop;
	profit_4_prop = acc->LimitOptions->optLimit_4_Prop;
}

void Limit::UpdateProfits(bool withStop)
{
	interior_ptr<float> p1p = &profit_1_price;
	interior_ptr<float> p2p = &profit_2_price;
	interior_ptr<float> p3p = &profit_3_price;
	interior_ptr<float> p4p = &profit_4_price;
	interior_ptr<float> pstp = &(trigger->stopLossPrice);

	if (trigger->Trend == Side::sLONG)
	{
		profit_1_price = Math::Round((double)(trigger->TriggerPrice + (profit_1_dest * trigger->RiskByCents)), 2); FindRoundedNumber_Long(p1p, trigger->RoundANumber);
		if (profit_2_dest != 0) { profit_2_price = Math::Round((double)(trigger->TriggerPrice + (profit_2_dest * trigger->RiskByCents)), 2); FindRoundedNumber_Long(p2p, trigger->RoundANumber); }
		if (profit_3_dest != 0) { profit_3_price = Math::Round((double)(trigger->TriggerPrice + (profit_3_dest * trigger->RiskByCents)), 2); FindRoundedNumber_Long(p3p, trigger->RoundANumber); }
		if (profit_4_dest != 0) { profit_4_price = Math::Round((double)(trigger->TriggerPrice + (profit_4_dest * trigger->RiskByCents)), 2); FindRoundedNumber_Long(p4p, trigger->RoundANumber); }
		if (withStop == true) FindRoundedNumber_Long(pstp, trigger->RoundStopNumber);
	}
	if (trigger->Trend == Side::sSHORT)
	{
		profit_1_price = Math::Round((double)(trigger->TriggerPrice - (profit_1_dest * trigger->RiskByCents)), 2); FindRoundedNumber_Short(p1p, trigger->RoundANumber);
		if (profit_2_dest != 0) { profit_2_price = Math::Round((double)(trigger->TriggerPrice - (profit_2_dest * trigger->RiskByCents)), 2); FindRoundedNumber_Short(p2p, trigger->RoundANumber); }
		if (profit_3_dest != 0) { profit_3_price = Math::Round((double)(trigger->TriggerPrice - (profit_3_dest * trigger->RiskByCents)), 2); FindRoundedNumber_Short(p3p, trigger->RoundANumber); }
		if (profit_4_dest != 0) { profit_4_price = Math::Round((double)(trigger->TriggerPrice - (profit_4_dest * trigger->RiskByCents)), 2); FindRoundedNumber_Short(p4p, trigger->RoundANumber); }
		if (withStop == true) FindRoundedNumber_Short(pstp, trigger->RoundStopNumber);
	}
}

void Limit::FindRoundedNumber_Long(interior_ptr<float> profit_price, int X)
{
	float rounded;
	float p1;
	int pp;
	
	rounded = Math::Round((double)(X * trigger->RiskByCents / 100), 2);
	p1 = Math::Round((double)(*profit_price - rounded), 2);
	
	while (p1 < *profit_price)
	{
		pp = (int)(p1 * 100) % 100;
		if ( pp == 0 || pp == 50 || Math::Round((double)p1, 2) == Math::Round((double)trigger->BarsP->MostHigh, 2) )
		{
			*profit_price = (int)(p1 * 100) / 100.0 - 0.02;
			break;
		}
		p1 += 0.01;
	}
}

void Limit::FindRoundedNumber_Short(interior_ptr<float> profit_price, int X)
{
	float rounded;
	float p1;
	int pp;

	rounded = Math::Round((double)(X * trigger->RiskByCents / 100), 2);
	p1 = Math::Round((double)(*profit_price + rounded), 2);
	
	while (p1 > *profit_price)
	{
		pp = (int)(p1 * 100) % 100;
		if ( pp == 0 || pp == 50 || Math::Round((double)p1, 2) == Math::Round((double)trigger->BarsP->MostLow, 2) )
		{
			*profit_price = (int)(p1 * 100) / 100.0 + 0.02;
			break;
		}
		p1 -= 0.01;
	}
}

void Limit::CalculateSizes()
{
	int Q;

	Q = trigger->QuantityFilled;

	if (Profit_1_prop == Propo::pAll)
		profit_1_size = Q;

	if (Profit_1_prop == Propo::pHalf && Profit_2_prop == Propo::pHalf)
	{
		profit_1_size = RoundInt( Q / 2 );
		profit_2_size = Q - profit_1_size;
	}

	if (Profit_1_prop == Propo::pHalf && Profit_2_prop == Propo::pQuarter && Profit_3_prop == Propo::pQuarter)
	{
		profit_1_size = RoundInt( Q / 2 );
		profit_2_size = RoundInt( (Q - profit_1_size) / 2 );
		profit_3_size = Q - profit_1_size - profit_2_size;
	}

	if (Profit_1_prop == Propo::pThird && Profit_2_prop == Propo::pThird && Profit_3_prop == Propo::pThird)
	{
		profit_1_size = RoundInt( Q / 3 );
		profit_2_size = RoundInt( (Q - profit_1_size) / 2 );
		profit_3_size = Q - profit_1_size - profit_2_size;
	}

	if (Profit_1_prop == Propo::pQuarter && Profit_2_prop == Propo::pQuarter && Profit_3_prop == Propo::pQuarter && Profit_4_prop == Propo::pQuarter)
	{
		profit_1_size = RoundInt( Q / 4 );
		profit_2_size = RoundInt( (Q - profit_1_size) / 3 );
		profit_3_size = RoundInt( (Q - profit_1_size - profit_2_size) / 2 );
		profit_4_size = Q - profit_1_size - profit_2_size - profit_3_size;
	}

	if (Profit_1_prop == Propo::pQuarter && Profit_2_prop == Propo::pHalf && Profit_3_prop == Propo::pQuarter)
	{
		profit_2_size = RoundInt( Q / 2 );
		profit_1_size = RoundInt( (Q - profit_2_size) / 2 );
		profit_3_size = Q - profit_1_size - profit_2_size;
	}

	if (Profit_1_prop == Propo::pQuarter && Profit_2_prop == Propo::pQuarter && Profit_3_prop == Propo::pHalf)
	{
		profit_3_size = RoundInt( Q / 2 );
		profit_1_size = RoundInt( (Q - profit_3_size) / 2 );
		profit_2_size = Q - profit_1_size - profit_3_size;
	}
}

int Limit::RoundInt(int num)
{
	num += 10;
	return (num / 10) * 10;
}
